package com.cherry.utils;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * 用于记录日志的工具类，它里面提供了公共的代码
 */
@Component("logger")
@Aspect// 表示当前类是一个切面类
public class Logger {

    @Pointcut("execution(* com.cherry.service.impl.*.*(..))")
    public void pt1() {}


    /**
     * 用于打印日志：计划让其在切入点方法执行之前执行(切入点)
     */
    public void printLog() {
        System.out.println("Logger类中的printLog方法开始记录日志了");
    }



//    @Before(value = "pt1()")
    public void beforeLog() {
        System.out.println("前置通知日志记录");
    }


//    @AfterReturning(value = "pt1()")
    public void afterLog() {
        System.out.println("后置通知日志记录");
    }


//    @AfterThrowing(value = "pt1()")
    public void exceptionLog() {
        System.out.println("异常通知日志记录");
    }


//    @After(value = "pt1()")
    public void finallyLog() {
        System.out.println("执行完毕通知日志记录");
    }


    /**
     * 环绕通知：
     * Spring框架为我们提供了一个接口：ProceedingJoinPoint。该接口有一个方法proceed();
     * 该方法就相当于明确调用切入点的方法
     *
     */
    @Around(value = "pt1()")
    public Object aroundLog(ProceedingJoinPoint proceedingJoinPoint) {
        Object proceed = null;
        try {
            System.out.println("环绕通知日志记录：前置 ");
            Object[] args = proceedingJoinPoint.getArgs(); // 获取方法的参数列表
            proceed = proceedingJoinPoint.proceed(args);// 明确调用业务层方法，（切入点方法）
            System.out.println("环绕通知日志记录：后置 ");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("环绕通知日志记录：异常 ");
        } finally {
            System.out.println("环绕通知日志记录：最终");
        }
        return proceed;

    }
}
